﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Net;
using Newtonsoft.Json;
using System.IO;

namespace xkcdViewer
{
    public partial class Form1 : Form
    {
        int startNumber = 0;
        int currentNumber = 0;
		Random rdm;
		List<int> alreadyRdm = new List<int>();
		xkcdInfo thisComic;
		bool doNotChange = false;
		
        public Form1()
        {
            InitializeComponent();
			rdm = new Random(DateTime.Now.Millisecond * DateTime.Now.Second);
			loadXkcd();
        }

        private void loadXkcd(int Number)
        {
            currentNumber = Number;
            imgBox.Image = null;
            pb.Visible = true;

			using (WebClient client = new WebClient())
			{
				try
				{
					client.DownloadStringCompleted += client_DownloadStringCompleted;
					client.DownloadStringAsync(new Uri("http://xkcd.com/" + Number.ToString() + "/info.0.json"));
				}
				catch (Exception ex)
				{
					MessageBox.Show("Couldn't retrieve newest xkcd. Error: Couldn't retrieve json string from xkcd." + Environment.NewLine + Environment.NewLine + ex, "Error");
				}
			}
        }

        private void loadXkcd()
        {
            imgBox.Image = null;
            pb.Visible = true;
			using (WebClient client = new WebClient())
			{
				try
				{
					client.DownloadStringCompleted += client_DownloadStringCompleted;
					client.DownloadStringAsync(new Uri("http://xkcd.com/info.0.json"));
				}
				catch (Exception ex)
				{
					MessageBox.Show("Couldn't retrieve newest xkcd. Error: Couldn't retrieve json string from xkcd." + Environment.NewLine + Environment.NewLine + ex, "Error");
				}
			}
        }

        private void client_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
        {
            try
            {
                string jsonString = e.Result;
                thisComic = JsonConvert.DeserializeObject<xkcdInfo>(jsonString);
                showComic();
            }
            catch 
            {
                altLbl.Text = "No xkcd exists at this number.";
                pb.Visible = false;
            }
        }

		private void showComic()
		{
			currentNumber = thisComic.num;
			if (doNotChange == false)
			{
				doNotChange = true;
				startNumber = thisComic.num;
			}

			try
			{
				this.Text = "xkcdViewer - " + thisComic.title;
				dateLbl.Text = "Date: " + thisComic.month + "/" + thisComic.day + "/" + thisComic.year + " |";
				altLbl.Text = thisComic.alt;

				using (WebClient imgDl = new WebClient())
				{
					imgDl.DownloadDataCompleted += imgDl_DownloadDataCompleted;
					imgDl.DownloadDataAsync(new Uri(thisComic.img));
				}
			}
			catch (Exception ex)
			{
				MessageBox.Show("Failed loading xkcd." + Environment.NewLine + Environment.NewLine + ex, "Error");
			}
		}

		void imgDl_DownloadDataCompleted(object sender, DownloadDataCompletedEventArgs e)
		{
			using (MemoryStream stream = new MemoryStream(e.Result))
			{
				imgBox.Image = Image.FromStream(stream);
			}
			pb.Visible = false;
		}

        private void randomToolStripMenuItem_Click(object sender, EventArgs e)
        {
            int currentRdm;

			while (true)
			{
				currentRdm = rdm.Next(1, startNumber);

				if (!alreadyRdm.Contains(currentRdm))
				{
					alreadyRdm.Add(currentRdm);
					break;
				}
			}

            loadXkcd(currentRdm);
        }

        private void goToToolStripMenuItem_Click(object sender, EventArgs e)
        {
            xkcdViewer.xkcdNum num = new xkcdViewer.xkcdNum();
            num.ShowDialog();

            if (num.selectedNum != null)
            {
                loadXkcd(num.selectedNum);
            }
        }

		#region Misc Event Handlers
		private void Form1_KeyDown(object sender, KeyEventArgs e)
		{
			if (e.KeyData == Keys.Left)
			{
				loadXkcd(currentNumber - 1);
			}
			else if (e.KeyData == Keys.Right)
			{
				loadXkcd(currentNumber + 1);
			}
			else if (e.KeyData == Keys.Down)
			{
				panel1.AutoScrollPosition = new Point(panel1.HorizontalScroll.Value, panel1.VerticalScroll.Value + 40);
			}
			else if (e.KeyData == Keys.Up)
			{
				panel1.AutoScrollPosition = new Point(panel1.HorizontalScroll.Value, panel1.VerticalScroll.Value - 40);
			}
		}

		private void copyPermalinkToolStripMenuItem_Click(object sender, EventArgs e)
		{
			Clipboard.SetText("http://xkcd.com/" + currentNumber + "/");
		}

		private void whatNumberToolStripMenuItem_Click(object sender, EventArgs e)
		{
			MessageBox.Show("xkcd number " + thisComic.num, "What number?");
		}

		private void copyImageURLToolStripMenuItem_Click(object sender, EventArgs e)
		{
			Clipboard.SetText(thisComic.img);
		}

		private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
		{
			MessageBox.Show("xkcdViewer for Windows <Andrew Kim>. Comics are property of xkcd." + Environment.NewLine + "Version " + System.Reflection.Assembly.GetExecutingAssembly().GetName().Version, "About");
		}

		private void codePlexToolStripMenuItem_Click(object sender, EventArgs e)
		{
			System.Diagnostics.Process.Start("http://xkcdViewer.codeplex.com/");
		}

		private void latestToolStripMenuItem_Click(object sender, EventArgs e)
		{
			loadXkcd();
		}

		private void toolStripMenuItem1_Click(object sender, EventArgs e)
		{
			loadXkcd(currentNumber - 1);
		}

		private void toolStripMenuItem2_Click(object sender, EventArgs e)
		{
			loadXkcd(currentNumber + 1);
		}
		#endregion
	}
}
